<h1 id="菜单和工具栏">菜单和工具栏</h1>
<p>这个章节，我们会创建状态栏、菜单和工具栏。菜单是一组位于菜单栏的命令。工具栏是应用的一些常用工具按钮。状态栏显示一些状态信息，通常在应用的底部。</p>
<h2 id="主窗口">主窗口</h2>
<p><code>QMainWindow</code>提供了主窗口的功能，使用它能创建一些简单的状态栏、工具栏和菜单栏。</p>
<p>主窗口是下面这些窗口的合称，所以教程在最下方。</p>
<h2 id="状态栏">状态栏</h2>
<p>状态栏是用来显示应用的状态信息的组件。</p>
<div class="sourceCode" id="cb1"><pre><code class="language-python"><a class="sourceLine" id="cb1-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb1-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb1-3" data-line-number="3"></a>
<a class="sourceLine" id="cb1-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb1-6" data-line-number="6"></a>
<a class="sourceLine" id="cb1-7" data-line-number="7"><span class="co">This program creates a statusbar.</span></a>
<a class="sourceLine" id="cb1-8" data-line-number="8"></a>
<a class="sourceLine" id="cb1-9" data-line-number="9"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb1-10" data-line-number="10"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb1-11" data-line-number="11"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb1-12" data-line-number="12"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb1-13" data-line-number="13"></a>
<a class="sourceLine" id="cb1-14" data-line-number="14"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb1-15" data-line-number="15"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QApplication</a>
<a class="sourceLine" id="cb1-16" data-line-number="16"></a>
<a class="sourceLine" id="cb1-17" data-line-number="17"></a>
<a class="sourceLine" id="cb1-18" data-line-number="18"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb1-19" data-line-number="19">    </a>
<a class="sourceLine" id="cb1-20" data-line-number="20">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb1-21" data-line-number="21">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb1-22" data-line-number="22">        </a>
<a class="sourceLine" id="cb1-23" data-line-number="23">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb1-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb1-25" data-line-number="25">        </a>
<a class="sourceLine" id="cb1-26" data-line-number="26">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb1-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb1-28" data-line-number="28">        <span class="va">self</span>.statusBar().showMessage(<span class="st">&#39;Ready&#39;</span>)</a>
<a class="sourceLine" id="cb1-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb1-30" data-line-number="30">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">250</span>, <span class="dv">150</span>)</a>
<a class="sourceLine" id="cb1-31" data-line-number="31">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Statusbar&#39;</span>)    </a>
<a class="sourceLine" id="cb1-32" data-line-number="32">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb1-33" data-line-number="33"></a>
<a class="sourceLine" id="cb1-34" data-line-number="34"></a>
<a class="sourceLine" id="cb1-35" data-line-number="35"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb1-36" data-line-number="36">    </a>
<a class="sourceLine" id="cb1-37" data-line-number="37">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb1-38" data-line-number="38">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb1-39" data-line-number="39">    sys.exit(app.exec_())</a></code></pre></div>
<p>状态栏是由QMainWindow创建的。</p>
<pre><code class="language-python">self.statusBar().showMessage(&#39;Ready&#39;)</code></pre>
<p>调用<code>QtGui.QMainWindow</code>类的<code>statusBar()</code>方法，创建状态栏。第一次调用创建一个状态栏，返回一个状态栏对象。<code>showMessage()</code>方法在状态栏上显示一条信息。</p>
<p>程序预览： <img class="whitelist" src="docs/PyQt5/images/2-status.png" alt="status" /></p>
<h2 id="菜单栏">菜单栏</h2>
<p>菜单栏是非常常用的。是一组命令的集合（Mac OS下状态栏的显示不一样，为了得到最相似的外观，我们增加了一句<code>menubar.setNativeMenuBar(False)</code>)。</p>
<div class="sourceCode" id="cb3"><pre><code class="language-python"><a class="sourceLine" id="cb3-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb3-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb3-3" data-line-number="3"></a>
<a class="sourceLine" id="cb3-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb3-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb3-6" data-line-number="6"></a>
<a class="sourceLine" id="cb3-7" data-line-number="7"><span class="co">This program creates a menubar. The</span></a>
<a class="sourceLine" id="cb3-8" data-line-number="8"><span class="co">menubar has one menu with an exit action.</span></a>
<a class="sourceLine" id="cb3-9" data-line-number="9"></a>
<a class="sourceLine" id="cb3-10" data-line-number="10"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb3-11" data-line-number="11"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb3-12" data-line-number="12"><span class="co">Last edited: January 2017</span></a>
<a class="sourceLine" id="cb3-13" data-line-number="13"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb3-14" data-line-number="14"></a>
<a class="sourceLine" id="cb3-15" data-line-number="15"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb3-16" data-line-number="16"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QAction, qApp, QApplication</a>
<a class="sourceLine" id="cb3-17" data-line-number="17"><span class="im">from</span> PyQt5.QtGui <span class="im">import</span> QIcon</a>
<a class="sourceLine" id="cb3-18" data-line-number="18"></a>
<a class="sourceLine" id="cb3-19" data-line-number="19"></a>
<a class="sourceLine" id="cb3-20" data-line-number="20"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb3-21" data-line-number="21">    </a>
<a class="sourceLine" id="cb3-22" data-line-number="22">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb3-23" data-line-number="23">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb3-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb3-25" data-line-number="25">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb3-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb3-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb3-28" data-line-number="28">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb3-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb3-30" data-line-number="30">        exitAct <span class="op">=</span> QAction(QIcon(<span class="st">&#39;exit.png&#39;</span>), <span class="st">&#39;&amp;Exit&#39;</span>, <span class="va">self</span>)        </a>
<a class="sourceLine" id="cb3-31" data-line-number="31">        exitAct.setShortcut(<span class="st">&#39;Ctrl+Q&#39;</span>)</a>
<a class="sourceLine" id="cb3-32" data-line-number="32">        exitAct.setStatusTip(<span class="st">&#39;Exit application&#39;</span>)</a>
<a class="sourceLine" id="cb3-33" data-line-number="33">        exitAct.triggered.<span class="ex">connect</span>(qApp.quit)</a>
<a class="sourceLine" id="cb3-34" data-line-number="34"></a>
<a class="sourceLine" id="cb3-35" data-line-number="35">        <span class="va">self</span>.statusBar()</a>
<a class="sourceLine" id="cb3-36" data-line-number="36"></a>
<a class="sourceLine" id="cb3-37" data-line-number="37">        menubar <span class="op">=</span> <span class="va">self</span>.menuBar()</a>
<a class="sourceLine" id="cb3-38" data-line-number="38">        fileMenu <span class="op">=</span> menubar.addMenu(<span class="st">&#39;&amp;File&#39;</span>)</a>
<a class="sourceLine" id="cb3-39" data-line-number="39">        fileMenu.addAction(exitAct)</a>
<a class="sourceLine" id="cb3-40" data-line-number="40">        </a>
<a class="sourceLine" id="cb3-41" data-line-number="41">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb3-42" data-line-number="42">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Simple menu&#39;</span>)    </a>
<a class="sourceLine" id="cb3-43" data-line-number="43">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb3-44" data-line-number="44">        </a>
<a class="sourceLine" id="cb3-45" data-line-number="45">        </a>
<a class="sourceLine" id="cb3-46" data-line-number="46"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb3-47" data-line-number="47">    </a>
<a class="sourceLine" id="cb3-48" data-line-number="48">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb3-49" data-line-number="49">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb3-50" data-line-number="50">    sys.exit(app.exec_())</a></code></pre></div>
<p>我们创建了只有一个命令的菜单栏，这个命令就是终止应用。同时也创建了一个状态栏。而且还能使用快捷键<code>Ctrl+Q</code>退出应用。</p>
<pre><code class="language-python">exitAct = QAction(QIcon(&#39;exit.png&#39;), &#39;&amp;Exit&#39;, self)        
exitAct.setShortcut(&#39;Ctrl+Q&#39;)
exitAct.setStatusTip(&#39;Exit application&#39;)</code></pre>
<p><code>QAction</code>是菜单栏、工具栏或者快捷键的动作的组合。前面两行，我们创建了一个图标、一个exit的标签和一个快捷键组合，都执行了一个动作。第三行，创建了一个状态栏，当鼠标悬停在菜单栏的时候，能显示当前状态。</p>
<pre><code class="language-python">exitAct.triggered.connect(qApp.quit)</code></pre>
<p>当执行这个指定的动作时，就触发了一个事件。这个事件跟<code>QApplication的quit()</code>行为相关联，所以这个动作就能终止这个应用。</p>
<pre><code class="language-python">menubar = self.menuBar()
fileMenu = menubar.addMenu(&#39;&amp;File&#39;)
fileMenu.addAction(exitAct)</code></pre>
<p><code>menuBar()</code>创建菜单栏。这里创建了一个菜单栏，并在上面添加了一个file菜单，并关联了点击退出应用的事件。</p>
<p>程序预览： <img class="whitelist" src="docs/PyQt5/images/2-menu.png" alt="menu" /></p>
<h2 id="子菜单">子菜单</h2>
<p>子菜单是嵌套在菜单里面的二级或者三级等的菜单。</p>
<div class="sourceCode" id="cb7"><pre><code class="language-python"><a class="sourceLine" id="cb7-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb7-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb7-3" data-line-number="3"></a>
<a class="sourceLine" id="cb7-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb7-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb7-6" data-line-number="6"></a>
<a class="sourceLine" id="cb7-7" data-line-number="7"><span class="co">This program creates a submenu.</span></a>
<a class="sourceLine" id="cb7-8" data-line-number="8"></a>
<a class="sourceLine" id="cb7-9" data-line-number="9"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb7-10" data-line-number="10"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb7-11" data-line-number="11"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb7-12" data-line-number="12"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb7-13" data-line-number="13"></a>
<a class="sourceLine" id="cb7-14" data-line-number="14"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb7-15" data-line-number="15"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QAction, QMenu, QApplication</a>
<a class="sourceLine" id="cb7-16" data-line-number="16"></a>
<a class="sourceLine" id="cb7-17" data-line-number="17"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb7-18" data-line-number="18">    </a>
<a class="sourceLine" id="cb7-19" data-line-number="19">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb7-20" data-line-number="20">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb7-21" data-line-number="21">        </a>
<a class="sourceLine" id="cb7-22" data-line-number="22">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb7-23" data-line-number="23">        </a>
<a class="sourceLine" id="cb7-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb7-25" data-line-number="25">    <span class="kw">def</span> initUI(<span class="va">self</span>):         </a>
<a class="sourceLine" id="cb7-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb7-27" data-line-number="27">        menubar <span class="op">=</span> <span class="va">self</span>.menuBar()</a>
<a class="sourceLine" id="cb7-28" data-line-number="28">        fileMenu <span class="op">=</span> menubar.addMenu(<span class="st">&#39;File&#39;</span>)</a>
<a class="sourceLine" id="cb7-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb7-30" data-line-number="30">        impMenu <span class="op">=</span> QMenu(<span class="st">&#39;Import&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb7-31" data-line-number="31">        impAct <span class="op">=</span> QAction(<span class="st">&#39;Import mail&#39;</span>, <span class="va">self</span>) </a>
<a class="sourceLine" id="cb7-32" data-line-number="32">        impMenu.addAction(impAct)</a>
<a class="sourceLine" id="cb7-33" data-line-number="33">        </a>
<a class="sourceLine" id="cb7-34" data-line-number="34">        newAct <span class="op">=</span> QAction(<span class="st">&#39;New&#39;</span>, <span class="va">self</span>)        </a>
<a class="sourceLine" id="cb7-35" data-line-number="35">        </a>
<a class="sourceLine" id="cb7-36" data-line-number="36">        fileMenu.addAction(newAct)</a>
<a class="sourceLine" id="cb7-37" data-line-number="37">        fileMenu.addMenu(impMenu)</a>
<a class="sourceLine" id="cb7-38" data-line-number="38">        </a>
<a class="sourceLine" id="cb7-39" data-line-number="39">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb7-40" data-line-number="40">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Submenu&#39;</span>)    </a>
<a class="sourceLine" id="cb7-41" data-line-number="41">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb7-42" data-line-number="42">        </a>
<a class="sourceLine" id="cb7-43" data-line-number="43">        </a>
<a class="sourceLine" id="cb7-44" data-line-number="44"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb7-45" data-line-number="45">    </a>
<a class="sourceLine" id="cb7-46" data-line-number="46">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb7-47" data-line-number="47">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb7-48" data-line-number="48">    sys.exit(app.exec_())</a></code></pre></div>
<p>这个例子里，有两个子菜单，一个在file菜单下面，一个在file的import下面。</p>
<pre><code class="language-python">impMenu = QMenu(&#39;Import&#39;, self)</code></pre>
<p>使用<code>QMenu</code>创建一个新菜单。</p>
<pre><code class="language-python">impAct = QAction(&#39;Import mail&#39;, self) 
impMenu.addAction(impAct)</code></pre>
<p>使用<code>addAction</code>添加一个动作。</p>
<p>程序预览： <img class="whitelist" src="docs/PyQt5/images/2-submenu.png" alt="submenu" /></p>
<h2 id="勾选菜单">勾选菜单</h2>
<p>下面是一个能勾选菜单的例子</p>
<div class="sourceCode" id="cb10"><pre><code class="language-python"><a class="sourceLine" id="cb10-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb10-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb10-3" data-line-number="3"></a>
<a class="sourceLine" id="cb10-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb10-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb10-6" data-line-number="6"></a>
<a class="sourceLine" id="cb10-7" data-line-number="7"><span class="co">This program creates a checkable menu.</span></a>
<a class="sourceLine" id="cb10-8" data-line-number="8"></a>
<a class="sourceLine" id="cb10-9" data-line-number="9"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb10-10" data-line-number="10"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb10-11" data-line-number="11"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb10-12" data-line-number="12"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb10-13" data-line-number="13"></a>
<a class="sourceLine" id="cb10-14" data-line-number="14"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb10-15" data-line-number="15"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QAction, QApplication</a>
<a class="sourceLine" id="cb10-16" data-line-number="16"></a>
<a class="sourceLine" id="cb10-17" data-line-number="17"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb10-18" data-line-number="18">    </a>
<a class="sourceLine" id="cb10-19" data-line-number="19">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb10-20" data-line-number="20">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb10-21" data-line-number="21">        </a>
<a class="sourceLine" id="cb10-22" data-line-number="22">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb10-23" data-line-number="23">        </a>
<a class="sourceLine" id="cb10-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb10-25" data-line-number="25">    <span class="kw">def</span> initUI(<span class="va">self</span>):         </a>
<a class="sourceLine" id="cb10-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb10-27" data-line-number="27">        <span class="va">self</span>.statusbar <span class="op">=</span> <span class="va">self</span>.statusBar()</a>
<a class="sourceLine" id="cb10-28" data-line-number="28">        <span class="va">self</span>.statusbar.showMessage(<span class="st">&#39;Ready&#39;</span>)</a>
<a class="sourceLine" id="cb10-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb10-30" data-line-number="30">        menubar <span class="op">=</span> <span class="va">self</span>.menuBar()</a>
<a class="sourceLine" id="cb10-31" data-line-number="31">        viewMenu <span class="op">=</span> menubar.addMenu(<span class="st">&#39;View&#39;</span>)</a>
<a class="sourceLine" id="cb10-32" data-line-number="32">        </a>
<a class="sourceLine" id="cb10-33" data-line-number="33">        viewStatAct <span class="op">=</span> QAction(<span class="st">&#39;View statusbar&#39;</span>, <span class="va">self</span>, checkable<span class="op">=</span><span class="va">True</span>)</a>
<a class="sourceLine" id="cb10-34" data-line-number="34">        viewStatAct.setStatusTip(<span class="st">&#39;View statusbar&#39;</span>)</a>
<a class="sourceLine" id="cb10-35" data-line-number="35">        viewStatAct.setChecked(<span class="va">True</span>)</a>
<a class="sourceLine" id="cb10-36" data-line-number="36">        viewStatAct.triggered.<span class="ex">connect</span>(<span class="va">self</span>.toggleMenu)</a>
<a class="sourceLine" id="cb10-37" data-line-number="37">        </a>
<a class="sourceLine" id="cb10-38" data-line-number="38">        viewMenu.addAction(viewStatAct)</a>
<a class="sourceLine" id="cb10-39" data-line-number="39">        </a>
<a class="sourceLine" id="cb10-40" data-line-number="40">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb10-41" data-line-number="41">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Check menu&#39;</span>)    </a>
<a class="sourceLine" id="cb10-42" data-line-number="42">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb10-43" data-line-number="43">        </a>
<a class="sourceLine" id="cb10-44" data-line-number="44">    <span class="kw">def</span> toggleMenu(<span class="va">self</span>, state):</a>
<a class="sourceLine" id="cb10-45" data-line-number="45">        </a>
<a class="sourceLine" id="cb10-46" data-line-number="46">        <span class="cf">if</span> state:</a>
<a class="sourceLine" id="cb10-47" data-line-number="47">            <span class="va">self</span>.statusbar.show()</a>
<a class="sourceLine" id="cb10-48" data-line-number="48">        <span class="cf">else</span>:</a>
<a class="sourceLine" id="cb10-49" data-line-number="49">            <span class="va">self</span>.statusbar.hide()</a>
<a class="sourceLine" id="cb10-50" data-line-number="50">       </a>
<a class="sourceLine" id="cb10-51" data-line-number="51">        </a>
<a class="sourceLine" id="cb10-52" data-line-number="52"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb10-53" data-line-number="53">    </a>
<a class="sourceLine" id="cb10-54" data-line-number="54">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb10-55" data-line-number="55">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb10-56" data-line-number="56">    sys.exit(app.exec_())</a></code></pre></div>
<p>本例创建了一个行为菜单。这个行为／动作能切换状态栏显示或者隐藏。</p>
<pre><code class="language-python">viewStatAct = QAction(&#39;View statusbar&#39;, self, checkable=True)</code></pre>
<p>用<code>checkable</code>选项创建一个能选中的菜单。</p>
<pre><code class="language-python">viewStatAct.setChecked(True)</code></pre>
<p>默认设置为选中状态。</p>
<pre><code class="language-python">def toggleMenu(self, state):
    
    if state:
        self.statusbar.show()
    else:
        self.statusbar.hide()</code></pre>
<p>依据选中状态切换状态栏的显示与否。 程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/2-checkmenu.png" alt="checkmenu" />
</figure>
<h2 id="右键菜单">右键菜单</h2>
<p>右键菜单也叫弹出框（！？），是在某些场合下显示的一组命令。例如，Opera浏览器里，网页上的右键菜单里会有刷新，返回或者查看页面源代码。如果在工具栏上右键，会得到一个不同的用来管理工具栏的菜单。</p>
<div class="sourceCode" id="cb14"><pre><code class="language-python"><a class="sourceLine" id="cb14-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb14-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb14-3" data-line-number="3"></a>
<a class="sourceLine" id="cb14-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb14-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb14-6" data-line-number="6"></a>
<a class="sourceLine" id="cb14-7" data-line-number="7"><span class="co">This program creates a context menu.</span></a>
<a class="sourceLine" id="cb14-8" data-line-number="8"></a>
<a class="sourceLine" id="cb14-9" data-line-number="9"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb14-10" data-line-number="10"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb14-11" data-line-number="11"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb14-12" data-line-number="12"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb14-13" data-line-number="13"></a>
<a class="sourceLine" id="cb14-14" data-line-number="14"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb14-15" data-line-number="15"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, qApp, QMenu, QApplication</a>
<a class="sourceLine" id="cb14-16" data-line-number="16"></a>
<a class="sourceLine" id="cb14-17" data-line-number="17"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb14-18" data-line-number="18">    </a>
<a class="sourceLine" id="cb14-19" data-line-number="19">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb14-20" data-line-number="20">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb14-21" data-line-number="21">        </a>
<a class="sourceLine" id="cb14-22" data-line-number="22">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb14-23" data-line-number="23">        </a>
<a class="sourceLine" id="cb14-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb14-25" data-line-number="25">    <span class="kw">def</span> initUI(<span class="va">self</span>):         </a>
<a class="sourceLine" id="cb14-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb14-27" data-line-number="27">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb14-28" data-line-number="28">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Context menu&#39;</span>)    </a>
<a class="sourceLine" id="cb14-29" data-line-number="29">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb14-30" data-line-number="30">    </a>
<a class="sourceLine" id="cb14-31" data-line-number="31">    </a>
<a class="sourceLine" id="cb14-32" data-line-number="32">    <span class="kw">def</span> contextMenuEvent(<span class="va">self</span>, event):</a>
<a class="sourceLine" id="cb14-33" data-line-number="33">       </a>
<a class="sourceLine" id="cb14-34" data-line-number="34">           cmenu <span class="op">=</span> QMenu(<span class="va">self</span>)</a>
<a class="sourceLine" id="cb14-35" data-line-number="35">           </a>
<a class="sourceLine" id="cb14-36" data-line-number="36">           newAct <span class="op">=</span> cmenu.addAction(<span class="st">&quot;New&quot;</span>)</a>
<a class="sourceLine" id="cb14-37" data-line-number="37">           opnAct <span class="op">=</span> cmenu.addAction(<span class="st">&quot;Open&quot;</span>)</a>
<a class="sourceLine" id="cb14-38" data-line-number="38">           quitAct <span class="op">=</span> cmenu.addAction(<span class="st">&quot;Quit&quot;</span>)</a>
<a class="sourceLine" id="cb14-39" data-line-number="39">           action <span class="op">=</span> cmenu.exec_(<span class="va">self</span>.mapToGlobal(event.pos()))</a>
<a class="sourceLine" id="cb14-40" data-line-number="40">           </a>
<a class="sourceLine" id="cb14-41" data-line-number="41">           <span class="cf">if</span> action <span class="op">==</span> quitAct:</a>
<a class="sourceLine" id="cb14-42" data-line-number="42">               qApp.quit()</a>
<a class="sourceLine" id="cb14-43" data-line-number="43">       </a>
<a class="sourceLine" id="cb14-44" data-line-number="44">        </a>
<a class="sourceLine" id="cb14-45" data-line-number="45"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb14-46" data-line-number="46">    </a>
<a class="sourceLine" id="cb14-47" data-line-number="47">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb14-48" data-line-number="48">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb14-49" data-line-number="49">    sys.exit(app.exec_())</a></code></pre></div>
<p>还是使用<code>contextMenuEvent()</code>方法实现这个菜单。</p>
<pre><code class="language-python">action = cmenu.exec_(self.mapToGlobal(event.pos()))</code></pre>
<p>使用<code>exec_()</code>方法显示菜单。从鼠标右键事件对象中获得当前坐标。<code>mapToGlobal()</code>方法把当前组件的相对坐标转换为窗口（window）的绝对坐标。</p>
<pre><code class="language-python">if action == quitAct:
    qApp.quit()</code></pre>
<p>如果右键菜单里触发了事件，也就触发了退出事件，执行关闭菜单行为。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/2-contextmenu.png" alt="contextmenu" />
</figure>
<h2 id="工具栏">工具栏</h2>
<p>菜单栏包含了所有的命令，工具栏就是常用的命令的集合。</p>
<div class="sourceCode" id="cb17"><pre><code class="language-python"><a class="sourceLine" id="cb17-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb17-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb17-3" data-line-number="3"></a>
<a class="sourceLine" id="cb17-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb17-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb17-6" data-line-number="6"></a>
<a class="sourceLine" id="cb17-7" data-line-number="7"><span class="co">This program creates a toolbar.</span></a>
<a class="sourceLine" id="cb17-8" data-line-number="8"><span class="co">The toolbar has one action, which</span></a>
<a class="sourceLine" id="cb17-9" data-line-number="9"><span class="co">terminates the application, if triggered.</span></a>
<a class="sourceLine" id="cb17-10" data-line-number="10"></a>
<a class="sourceLine" id="cb17-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb17-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb17-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb17-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb17-15" data-line-number="15"></a>
<a class="sourceLine" id="cb17-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb17-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QAction, qApp, QApplication</a>
<a class="sourceLine" id="cb17-18" data-line-number="18"><span class="im">from</span> PyQt5.QtGui <span class="im">import</span> QIcon</a>
<a class="sourceLine" id="cb17-19" data-line-number="19"></a>
<a class="sourceLine" id="cb17-20" data-line-number="20"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb17-21" data-line-number="21">    </a>
<a class="sourceLine" id="cb17-22" data-line-number="22">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb17-23" data-line-number="23">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb17-24" data-line-number="24">        </a>
<a class="sourceLine" id="cb17-25" data-line-number="25">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb17-26" data-line-number="26">        </a>
<a class="sourceLine" id="cb17-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb17-28" data-line-number="28">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb17-29" data-line-number="29">        </a>
<a class="sourceLine" id="cb17-30" data-line-number="30">        exitAct <span class="op">=</span> QAction(QIcon(<span class="st">&#39;exit24.png&#39;</span>), <span class="st">&#39;Exit&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb17-31" data-line-number="31">        exitAct.setShortcut(<span class="st">&#39;Ctrl+Q&#39;</span>)</a>
<a class="sourceLine" id="cb17-32" data-line-number="32">        exitAct.triggered.<span class="ex">connect</span>(qApp.quit)</a>
<a class="sourceLine" id="cb17-33" data-line-number="33">        </a>
<a class="sourceLine" id="cb17-34" data-line-number="34">        <span class="va">self</span>.toolbar <span class="op">=</span> <span class="va">self</span>.addToolBar(<span class="st">&#39;Exit&#39;</span>)</a>
<a class="sourceLine" id="cb17-35" data-line-number="35">        <span class="va">self</span>.toolbar.addAction(exitAct)</a>
<a class="sourceLine" id="cb17-36" data-line-number="36">        </a>
<a class="sourceLine" id="cb17-37" data-line-number="37">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">200</span>)</a>
<a class="sourceLine" id="cb17-38" data-line-number="38">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Toolbar&#39;</span>)    </a>
<a class="sourceLine" id="cb17-39" data-line-number="39">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb17-40" data-line-number="40">        </a>
<a class="sourceLine" id="cb17-41" data-line-number="41">        </a>
<a class="sourceLine" id="cb17-42" data-line-number="42"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb17-43" data-line-number="43">    </a>
<a class="sourceLine" id="cb17-44" data-line-number="44">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb17-45" data-line-number="45">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb17-46" data-line-number="46">    sys.exit(app.exec_())</a></code></pre></div>
<p>上面的例子中，我们创建了一个工具栏。这个工具栏只有一个退出应用的动作。</p>
<pre><code class="language-python">exitAct = QAction(QIcon(&#39;exit24.png&#39;), &#39;Exit&#39;, self)
exitAct.setShortcut(&#39;Ctrl+Q&#39;)
exitAct.triggered.connect(qApp.quit)</code></pre>
<p>和上面的菜单栏差不多，这里使用了一个行为对象，这个对象绑定了一个标签，一个图标和一个快捷键。这些行为被触发的时候，会调用<code>QtGui.QMainWindow</code>的quit方法退出应用。</p>
<pre><code class="language-python">self.toolbar = self.addToolBar(&#39;Exit&#39;)
self.toolbar.addAction(exitAct)</code></pre>
<p>把工具栏展示出来。</p>
<p>程序预览：</p>
<p><img class="whitelist" src="docs/PyQt5/images/2-toolbar.png" alt="toolbar" /> ## 主窗口</p>
<p>主窗口就是上面三种栏目的总称，现在我们把上面的三种栏在一个应用里展示出来。</p>
<blockquote>
<p>首先要自己弄个小图标，命名为exit24.png</p>
</blockquote>
<div class="sourceCode" id="cb20"><pre><code class="language-python"><a class="sourceLine" id="cb20-1" data-line-number="1"><span class="co">#!/usr/bin/python3</span></a>
<a class="sourceLine" id="cb20-2" data-line-number="2"><span class="co"># -*- coding: utf-8 -*-</span></a>
<a class="sourceLine" id="cb20-3" data-line-number="3"></a>
<a class="sourceLine" id="cb20-4" data-line-number="4"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb20-5" data-line-number="5"><span class="co">ZetCode PyQt5 tutorial </span></a>
<a class="sourceLine" id="cb20-6" data-line-number="6"></a>
<a class="sourceLine" id="cb20-7" data-line-number="7"><span class="co">This program creates a skeleton of</span></a>
<a class="sourceLine" id="cb20-8" data-line-number="8"><span class="co">a classic GUI application with a menubar,</span></a>
<a class="sourceLine" id="cb20-9" data-line-number="9"><span class="co">toolbar, statusbar, and a central widget. </span></a>
<a class="sourceLine" id="cb20-10" data-line-number="10"></a>
<a class="sourceLine" id="cb20-11" data-line-number="11"><span class="co">Author: Jan Bodnar</span></a>
<a class="sourceLine" id="cb20-12" data-line-number="12"><span class="co">Website: zetcode.com </span></a>
<a class="sourceLine" id="cb20-13" data-line-number="13"><span class="co">Last edited: August 2017</span></a>
<a class="sourceLine" id="cb20-14" data-line-number="14"><span class="co">&quot;&quot;&quot;</span></a>
<a class="sourceLine" id="cb20-15" data-line-number="15"></a>
<a class="sourceLine" id="cb20-16" data-line-number="16"><span class="im">import</span> sys</a>
<a class="sourceLine" id="cb20-17" data-line-number="17"><span class="im">from</span> PyQt5.QtWidgets <span class="im">import</span> QMainWindow, QTextEdit, QAction, QApplication</a>
<a class="sourceLine" id="cb20-18" data-line-number="18"><span class="im">from</span> PyQt5.QtGui <span class="im">import</span> QIcon</a>
<a class="sourceLine" id="cb20-19" data-line-number="19"></a>
<a class="sourceLine" id="cb20-20" data-line-number="20"></a>
<a class="sourceLine" id="cb20-21" data-line-number="21"><span class="kw">class</span> Example(QMainWindow):</a>
<a class="sourceLine" id="cb20-22" data-line-number="22">    </a>
<a class="sourceLine" id="cb20-23" data-line-number="23">    <span class="kw">def</span> <span class="fu">__init__</span>(<span class="va">self</span>):</a>
<a class="sourceLine" id="cb20-24" data-line-number="24">        <span class="bu">super</span>().<span class="fu">__init__</span>()</a>
<a class="sourceLine" id="cb20-25" data-line-number="25">        </a>
<a class="sourceLine" id="cb20-26" data-line-number="26">        <span class="va">self</span>.initUI()</a>
<a class="sourceLine" id="cb20-27" data-line-number="27">        </a>
<a class="sourceLine" id="cb20-28" data-line-number="28">        </a>
<a class="sourceLine" id="cb20-29" data-line-number="29">    <span class="kw">def</span> initUI(<span class="va">self</span>):               </a>
<a class="sourceLine" id="cb20-30" data-line-number="30">        </a>
<a class="sourceLine" id="cb20-31" data-line-number="31">        textEdit <span class="op">=</span> QTextEdit()</a>
<a class="sourceLine" id="cb20-32" data-line-number="32">        <span class="va">self</span>.setCentralWidget(textEdit)</a>
<a class="sourceLine" id="cb20-33" data-line-number="33"></a>
<a class="sourceLine" id="cb20-34" data-line-number="34">        exitAct <span class="op">=</span> QAction(QIcon(<span class="st">&#39;exit24.png&#39;</span>), <span class="st">&#39;Exit&#39;</span>, <span class="va">self</span>)</a>
<a class="sourceLine" id="cb20-35" data-line-number="35">        exitAct.setShortcut(<span class="st">&#39;Ctrl+Q&#39;</span>)</a>
<a class="sourceLine" id="cb20-36" data-line-number="36">        exitAct.setStatusTip(<span class="st">&#39;Exit application&#39;</span>)</a>
<a class="sourceLine" id="cb20-37" data-line-number="37">        exitAct.triggered.<span class="ex">connect</span>(<span class="va">self</span>.close)</a>
<a class="sourceLine" id="cb20-38" data-line-number="38"></a>
<a class="sourceLine" id="cb20-39" data-line-number="39">        <span class="va">self</span>.statusBar()</a>
<a class="sourceLine" id="cb20-40" data-line-number="40"></a>
<a class="sourceLine" id="cb20-41" data-line-number="41">        menubar <span class="op">=</span> <span class="va">self</span>.menuBar()</a>
<a class="sourceLine" id="cb20-42" data-line-number="42">        fileMenu <span class="op">=</span> menubar.addMenu(<span class="st">&#39;&amp;File&#39;</span>)</a>
<a class="sourceLine" id="cb20-43" data-line-number="43">        fileMenu.addAction(exitAct)</a>
<a class="sourceLine" id="cb20-44" data-line-number="44"></a>
<a class="sourceLine" id="cb20-45" data-line-number="45">        toolbar <span class="op">=</span> <span class="va">self</span>.addToolBar(<span class="st">&#39;Exit&#39;</span>)</a>
<a class="sourceLine" id="cb20-46" data-line-number="46">        toolbar.addAction(exitAct)</a>
<a class="sourceLine" id="cb20-47" data-line-number="47">        </a>
<a class="sourceLine" id="cb20-48" data-line-number="48">        <span class="va">self</span>.setGeometry(<span class="dv">300</span>, <span class="dv">300</span>, <span class="dv">350</span>, <span class="dv">250</span>)</a>
<a class="sourceLine" id="cb20-49" data-line-number="49">        <span class="va">self</span>.setWindowTitle(<span class="st">&#39;Main window&#39;</span>)    </a>
<a class="sourceLine" id="cb20-50" data-line-number="50">        <span class="va">self</span>.show()</a>
<a class="sourceLine" id="cb20-51" data-line-number="51">        </a>
<a class="sourceLine" id="cb20-52" data-line-number="52">        </a>
<a class="sourceLine" id="cb20-53" data-line-number="53"><span class="cf">if</span> <span class="va">__name__</span> <span class="op">==</span> <span class="st">&#39;__main__&#39;</span>:</a>
<a class="sourceLine" id="cb20-54" data-line-number="54">    </a>
<a class="sourceLine" id="cb20-55" data-line-number="55">    app <span class="op">=</span> QApplication(sys.argv)</a>
<a class="sourceLine" id="cb20-56" data-line-number="56">    ex <span class="op">=</span> Example()</a>
<a class="sourceLine" id="cb20-57" data-line-number="57">    sys.exit(app.exec_())</a></code></pre></div>
<p>上面的代码创建了一个很经典的菜单框架，有右键菜单，工具栏和状态栏。</p>
<pre><code class="language-python">textEdit = QTextEdit()
self.setCentralWidget(textEdit)</code></pre>
<p>这里创建了一个文本编辑区域，并把它放在<code>QMainWindow</code>的中间区域。这个组件或占满所有剩余的区域。</p>
<p>程序预览：</p>
<figure>
<img class="whitelist" src="docs/PyQt5/images/2-mainwindow.png" alt="mainwindow" />
</figure>
